//=======================================================================================
//
//  Purpose: Povide a container for the encoding of a character for display in an LED 
//           cube.
//
//  Copyright (C) 2011 Mark Stevens
//
//  This software is destributed under the MS-PL licence agreement a copy of which can
//  be found on the codeplex page http://netduinoledcontrol.codeplex.com and in the
//  Licence.txt file distributed with this project.
//
//=======================================================================================
using System;
using Microsoft.SPOT.Hardware;

namespace Coding4Fun.NetduinoLEDControl
{
    /// <summary>
    /// Hold the data necessary to define a firework in the LED cube.
    /// </summary>
    class Firework
    {
        #region Private variables

        /// <summary>
        /// Set up and seed the random number generator.
        /// </summary>
        private static Random _rand = new Random((int) (Utility.GetMachineTime().Ticks & 0xffffffff));

        #endregion

        #region Properties

        /// <summary>
        /// X coordinate of the firework in the cube.
        /// </summary>
        public int X { get; private set; }

        /// <summary>
        /// Z coordinate of the firework in the cube.
        /// </summary>
        public int Z { get; private set; }

        /// <summary>
        /// Current height of the firework.
        /// </summary>
        public int CurrentHeight { get; private set; }

        /// <summary>
        /// Maximum height of the firework.
        /// </summary>
        /// <remarks>
        /// When a firework reaches this height it explodes.
        /// </remarks>
        private int MaximumHeight { get; set; }

        /// <summary>
        /// Is the firework climbing?
        /// </summary>
        public bool IsClimbing { get; private set; }

        /// <summary>
        /// Is the firework exploding?
        /// </summary>
        public bool IsExploding { get; private set; }

        /// <summary>
        /// Shards which result from the explosion.
        /// </summary>
        public Point[] Shards { get; private set; }

        #endregion

        #region Constructor(s)

        /// <summary>
        /// Constructor for the firework.
        /// </summary>
        public Firework()
        {
            X = 2 + (_rand.Next() % 4);
            Z = 2 + (_rand.Next() % 4);
            CurrentHeight = 0;
            MaximumHeight = 6;
            IsClimbing = true;
            IsExploding = false;
        }

        #endregion

        #region Methods

        /// <summary>
        /// Move the firework or the explosion.
        /// </summary>
        /// <returns>True if this firework is still valid, false otherwise.</returns>
        public bool Move()
        {
            if (IsClimbing && (CurrentHeight == MaximumHeight))
            {
                IsClimbing = false;
                if (!IsExploding)
                {
                    IsExploding = true;
                    Shards = new Point[4];
                    for (int counter = 0; counter < 4; counter++)
                    {
                        Shards[counter] = new Point();
                    }
                    Shards[0].X = X;
                    Shards[0].Z = Z;
                    Shards[0].Y = CurrentHeight;
                    Shards[1].X = X;
                    Shards[1].Z = Z;
                    Shards[1].Y = CurrentHeight;
                    Shards[2].X = X;
                    Shards[2].Z = Z;
                    Shards[2].Y = CurrentHeight;
                    Shards[3].X = X;
                    Shards[3].Z = Z;
                    Shards[3].Y = CurrentHeight;
                }
            }
            else
            {
                CurrentHeight++;
            }
            if (IsExploding)
            {
                if ((CurrentHeight - Shards[0].Y) > 2)
                {
                    IsExploding = false;
                }
                else
                {
                    Shards[0].X--;
                    Shards[0].Y--;
                    Shards[1].X++;
                    Shards[1].Y--;
                    Shards[2].Z--;
                    Shards[2].Y--;
                    Shards[3].Z++;
                    Shards[3].Y--;
                }
            }
            return (IsClimbing | IsExploding);
        }

        #endregion
    }
}
